// 导出课表为高清图片（JPG）
async function exportScheduleImage() {
    try {
        const container = document.getElementById('scheduleContainer');
        if (!container) return;
        // 使用 2x 缩放获得更高清图片
        const scale = 4;
        const canvas = await html2canvas(container, {
            backgroundColor: '#ffffff',
            scale: scale,
            useCORS: true,
            logging: false,
            windowWidth: container.scrollWidth,
            windowHeight: container.scrollHeight
        });
        const dataUrl = canvas.toDataURL('image/jpeg', 0.95);
        const link = document.createElement('a');
        const ts = new Date().toISOString().slice(0,19).replace(/[:T]/g,'-');
        link.href = dataUrl;
        link.download = `课程表_${ts}.jpg`;
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
    } catch (e) {
        console.error(e);
        showError('导出图片失败，请重试');
    }
}
// 课程表页面JavaScript功能

let scheduleData = null;
let classId = null;
let scheduleType = 'class'; // 'class' 或 'teacher'

document.addEventListener('DOMContentLoaded', function() {
    // 获取ID和类型
    const pathParts = window.location.pathname.split('/');
    classId = pathParts[pathParts.length - 1];
    
    // 判断是班级还是教师课表
    if (window.location.pathname.includes('/teacher/')) {
        scheduleType = 'teacher';
    }
    
    if (classId) {
        loadScheduleData();
    } else {
        showError('无效的ID');
    }
    
    // 绑定事件
    bindEvents();
});

// 加载课程表数据
async function loadScheduleData() {
    showLoading();
    
    try {
        const apiUrl = scheduleType === 'teacher' ? `/api/teacher_schedule/${classId}` : `/api/schedule/${classId}`;
        const response = await fetch(apiUrl);
        
        if (!response.ok) {
            throw new Error(`HTTP ${response.status}: ${response.statusText}`);
        }
        
        scheduleData = await response.json();
        renderSchedule();
        renderCourseList();
        
    } catch (error) {
        console.error('加载课程表数据失败:', error);
        showError('加载课程表数据失败: ' + error.message);
    } finally {
        hideLoading();
    }
}

// 课程颜色映射
let courseColors = new Map();
let colorIndex = 0;
let nowLineTimer = null;
let nowIndicatorEnabled = false;

// 课程表配色方案
const colorThemes = {
    // 清新简约风 - 冷色系为主，适中饱和度
    fresh: [
        '#4A90E2', // 清新蓝
        '#7ED321', // 活力绿
        '#F5A623', // 温暖橙
        '#50E3C2', // 薄荷青
        '#B8E986', // 嫩绿色
        '#9013FE', // 优雅紫
        '#FF6B6B', // 珊瑚红
        '#4ECDC4', // 青绿色
        '#45B7D1', // 天空蓝
        '#96CEB4', // 淡绿色
        '#FFEAA7', // 柔和黄
        '#DDA0DD', // 淡紫色
    ],

    // 温暖学院风 - 暖色系为主
    warm: [
        '#FF7675', // 温暖红
        '#FDCB6E', // 金黄色
        '#E17055', // 橙红色
        '#A29BFE', // 淡紫色
        '#FD79A8', // 粉红色
        '#FDCB6E', // 蜂蜜色
        '#E84393', // 玫瑰色
        '#00B894', // 翡翠绿
        '#00CEC9', // 青色
        '#6C5CE7', // 紫色
        '#FF7675', // 珊瑚色
        '#74B9FF', // 蓝色
    ],

    // 商务专业风 - 中性色系，提高对比度
    professional: [
        '#2D3436', // 深灰蓝
        '#636E72', // 中性灰
        '#74B9FF', // 商务蓝
        '#00B894', // 专业绿
        '#FDCB6E', // 警示黄
        '#E17055', // 重点橙
        '#A29BFE', // 淡紫色
        '#FD79A8', // 强调粉
        '#00CEC9', // 青绿色
        '#6C5CE7', // 深紫色
        '#55A3FF', // 亮蓝色
        '#26DE81', // 成功绿
    ],

    // 护眼绿色系 - 以绿色为主，降低视觉疲劳
    eyecare: [
        '#00B894', // 主绿色
        '#55EFC4', // 浅绿色
        '#81ECEC', // 青绿色
        '#74B9FF', // 蓝绿色
        '#A29BFE', // 淡紫色
        '#FDCB6E', // 柔和黄
        '#FD79A8', // 淡粉色
        '#E17055', // 暖橙色
        '#00CEC9', // 青色
        '#6C5CE7', // 紫色
        '#26DE81', // 亮绿色
        '#45B7D1', // 天蓝色
    ]
};

// 主题信息
const themeInfo = {
    fresh: {
        name: '清新简约',
        description: '冷色系为主，视觉清爽，适合长时间使用',
        textColor: '#FFFFFF'
    },
    warm: {
        name: '温暖学院',
        description: '暖色系为主，温馨舒适，营造学习氛围',
        textColor: '#FFFFFF'
    },
    professional: {
        name: '商务专业',
        description: '中性色系，简洁大方，适合正式场合',
        textColor: '#FFFFFF'
    },
    eyecare: {
        name: '护眼绿色',
        description: '绿色系为主，保护视力，减少疲劳',
        textColor: '#FFFFFF'
    }
};

// 当前使用的主题（默认为清新简约）
let currentTheme = 'fresh';

// 获取当前主题的颜色调色板
function getCurrentColorPalette() {
    return colorThemes[currentTheme] || colorThemes.fresh;
}

// 获取当前主题的文字颜色
function getCurrentTextColor() {
    return themeInfo[currentTheme]?.textColor || '#FFFFFF';
}

// 切换主题
function switchTheme(themeName) {
    if (colorThemes[themeName]) {
        currentTheme = themeName;
        // 重置颜色映射
        courseColors.clear();
        colorIndex = 0;
        // 重新渲染课程表
        renderSchedule();
        // 更新主题选择器状态
        updateThemeSelector();
    }
}

// 获取课程颜色
function getCourseColor(courseName) {
    if (!courseColors.has(courseName)) {
        const palette = getCurrentColorPalette();
        courseColors.set(courseName, palette[colorIndex % palette.length]);
        colorIndex++;
    }
    return courseColors.get(courseName);
}

// 设置颜色主题
function setColorTheme(themeName) {
    if (colorThemes[themeName]) {
        currentTheme = themeName;
        // 重置颜色映射，重新分配颜色
        courseColors.clear();
        colorIndex = 0;
        // 如果页面已加载，重新渲染
        if (typeof renderSchedule === 'function' && scheduleData) {
            renderSchedule();
        }
    }
}

// 渲染课程表
function renderSchedule() {
    if (!scheduleData) return;

    // 重置颜色映射
    courseColors.clear();
    colorIndex = 0;

    // 更新页面标题
    if (scheduleType === 'teacher') {
        document.getElementById('className').textContent = scheduleData.teacher_info.teacher_name;
        document.getElementById('classInfo').textContent =
            `${scheduleData.teacher_info.department} | ${scheduleData.teacher_info.teacher_title} | ${scheduleData.teacher_info.semester} | 共 ${scheduleData.teacher_info.total_courses} 门课程`;
    } else {
        document.getElementById('className').textContent = scheduleData.class_info.class_name;
        document.getElementById('classInfo').textContent =
            `${scheduleData.class_info.semester} | 共 ${scheduleData.class_info.total_courses} 门课程`;
    }

    // 生成课程表表格
    const tbody = document.getElementById('scheduleBody');
    tbody.innerHTML = '';

    // 预处理课程数据，标记合并的课程
    const processedSchedule = preprocessScheduleForMerging(scheduleData.schedule_table);

    // 创建13行（对应13节课）
    for (let period = 1; period <= 13; period++) {
        const row = document.createElement('tr');

        // 时间列
        const timeCell = document.createElement('td');
        timeCell.className = 'time-slot';
        timeCell.innerHTML = `
            <div class="fw-bold">第${period}节</div>
            <div class="small">${scheduleData.time_slots[period]}</div>
        `;
        row.appendChild(timeCell);

        // 星期列（1-7对应周一到周日）
        for (let weekday = 1; weekday <= 7; weekday++) {
            const cellData = processedSchedule[weekday - 1][period - 1];

            // 如果这个单元格被合并了，跳过（不创建td）
            if (cellData && cellData.skip) {
                continue;
            }

            const cell = document.createElement('td');

            if (cellData && cellData.course) {
                // 设置单元格的rowspan
                if (cellData.span > 1) {
                    cell.rowSpan = cellData.span;
                }

                cell.innerHTML = createCourseCell(cellData.course, period, weekday, cellData.span);
            } else {
                cell.innerHTML = '';
            }

            row.appendChild(cell);
        }

        tbody.appendChild(row);
    }

    // 渲染完成后，尝试绘制当前时间指示线
    updateNowLine();
}

// 预处理课程表数据，处理课程合并
function preprocessScheduleForMerging(scheduleTable) {
    const processed = Array(7).fill().map(() => Array(13).fill(null));

    for (let weekday = 0; weekday < 7; weekday++) {
        for (let period = 0; period < 13; period++) {
            const course = scheduleTable[weekday][period];

            if (!course || processed[weekday][period]) {
                continue;
            }

            // 计算连续课程的跨度
            let span = 1;
            for (let nextPeriod = period + 1; nextPeriod < 13; nextPeriod++) {
                const nextCourse = scheduleTable[weekday][nextPeriod];

                if (nextCourse &&
                    nextCourse.course_name === course.course_name &&
                    nextCourse.teacher === course.teacher &&
                    nextCourse.location === course.location) {
                    span++;
                } else {
                    break;
                }
            }

            // 设置主课程单元格
            processed[weekday][period] = {
                course: course,
                span: span,
                skip: false
            };

            // 标记被合并的单元格
            for (let i = 1; i < span; i++) {
                if (period + i < 13) {
                    processed[weekday][period + i] = {
                        course: null,
                        span: 0,
                        skip: true
                    };
                }
            }
        }
    }

    return processed;
}

// 创建课程单元格
function createCourseCell(course, period, weekday, span = 1) {
    const isExperiment = course.is_experiment;
    const isWeekend = weekday >= 6; // 周六周日

    let cellClass = 'course-cell';
    if (isExperiment) cellClass += ' experiment';
    if (isWeekend) cellClass += ' weekend';

    // 根据跨度调整样式
    if (span > 1) {
        cellClass += ' merged-course';
    }

    const weekText = course.week_range ? course.week_range.range_text : '';

    // 使用课程名称获取颜色
    const courseColor = getCourseColor(course.course_name);
    const textColor = getCurrentTextColor();

    // 显示节次信息（如果是合并的课程）
    const periodInfo = span > 1 ? `第${period}-${period + span - 1}节` : `第${period}节`;

    return `
        <div class="${cellClass}"
             style="background: ${courseColor}; color: ${textColor};"
             data-course='${JSON.stringify(course)}'
             data-period="${period}"
             data-weekday="${weekday}"
             data-span="${span}"
             title="${course.course_name} - ${course.teacher} - ${course.location} (${periodInfo})">
            <div class="course-info">
                <div class="course-name">${course.course_name}</div>
                <div class="course-details">
                    <div>${course.teacher}</div>
                    <div>${course.location}</div>
                    ${span > 1 ? `<div class="period-info">${periodInfo}</div>` : ''}
                    <div class="small">${weekText}</div>
                </div>
            </div>
        </div>
    `;
}

// 渲染课程列表
function renderCourseList() {
    if (!scheduleData) return;
    
    const courseList = document.getElementById('courseList');
    courseList.innerHTML = '';
    
    // 按课程名称分组（去重）
    const uniqueCourses = new Map();
    
    scheduleData.courses.forEach(course => {
        const key = course.course_name;
        if (!uniqueCourses.has(key)) {
            uniqueCourses.set(key, course);
        }
    });
    
    // 渲染课程卡片
    uniqueCourses.forEach(course => {
        const courseCard = createCourseDetailCard(course);
        courseList.appendChild(courseCard);
    });
}

// 创建课程详情卡片
function createCourseDetailCard(course) {
    const isExperiment = course.is_experiment;
    const cardClass = isExperiment ? 'course-detail-card experiment' : 'course-detail-card';
    
    // 获取该课程的所有时间段
    const timeSlots = scheduleData.courses
        .filter(c => c.course_name === course.course_name)
        .map(c => {
            const weekday = scheduleData.weekdays[c.weekday];
            const timeRange = `${scheduleData.time_slots[c.start_period]}-${scheduleData.time_slots[c.end_period]}`;
            return `${weekday} ${timeRange}`;
        })
        .join(', ');
    
    const card = document.createElement('div');
    card.className = 'col-md-6 col-lg-4 mb-3';
    card.innerHTML = `
        <div class="card ${cardClass} h-100">
            <div class="card-body">
                <div class="d-flex justify-content-between align-items-start mb-2">
                    <h6 class="card-title text-primary mb-0">${course.course_name}</h6>
                    ${isExperiment ? '<span class="badge bg-danger">实验课</span>' : ''}
                </div>
                <div class="mb-2">
                    <small class="text-muted">
                        <i class="bi bi-person"></i> ${course.teacher}
                    </small>
                </div>
                <div class="mb-2">
                    <small class="text-muted">
                        <i class="bi bi-geo-alt"></i> ${course.location}
                    </small>
                </div>
                <div class="mb-2">
                    <small class="text-muted">
                        <i class="bi bi-clock"></i> ${timeSlots}
                    </small>
                </div>
                <div class="mb-2">
                    <small class="text-muted">
                        <i class="bi bi-calendar-week"></i> ${course.total_weeks}
                    </small>
                </div>
                <div class="d-flex justify-content-between align-items-center">
                    <small class="text-muted">
                        课程代码: ${course.course_code}
                    </small>
                    <button class="btn btn-sm btn-outline-primary" onclick="showCourseDetail('${course.course_name}')">
                        详情
                    </button>
                </div>
            </div>
        </div>
    `;
    
    return card;
}

// 显示课程详情
function showCourseDetail(courseName) {
    if (!scheduleData) return;
    
    const courses = scheduleData.courses.filter(c => c.course_name === courseName);
    if (courses.length === 0) return;
    
    const course = courses[0];
    const modal = new bootstrap.Modal(document.getElementById('courseModal'));
    
    // 构建详情内容
    const timeSlots = courses.map(c => {
        const weekday = scheduleData.weekdays[c.weekday];
        const timeRange = `${scheduleData.time_slots[c.start_period]}-${scheduleData.time_slots[c.end_period]}`;
        return `${weekday} ${timeRange}`;
    }).join('<br>');
    
    document.getElementById('courseModalTitle').textContent = course.course_name;
    document.getElementById('courseModalBody').innerHTML = `
        <div class="row">
            <div class="col-md-6">
                <h6>基本信息</h6>
                <table class="table table-sm">
                    <tr><td>课程名称</td><td>${course.course_name}</td></tr>
                    <tr><td>任课教师</td><td>${course.teacher}</td></tr>
                    <tr><td>上课地点</td><td>${course.location}</td></tr>
                    <tr><td>课程代码</td><td>${course.course_code}</td></tr>
                    <tr><td>课程类型</td><td>${course.is_experiment ? '实验课' : '理论课'}</td></tr>
                    <tr><td>上课周次</td><td>${course.total_weeks}</td></tr>
                    <tr><td>班级人数</td><td>${course.class_size}人</td></tr>
                </table>
            </div>
            <div class="col-md-6">
                <h6>上课时间</h6>
                <div class="mb-3">${timeSlots}</div>
                <h6>周次安排</h6>
                <div class="mb-3">${course.week_range ? course.week_range.range_text : '未知'}</div>
            </div>
        </div>
    `;
    
    modal.show();
}

// 更新主题选择器状态
function updateThemeSelector() {
    const currentThemeNameElement = document.getElementById('currentThemeName');
    const themeOptions = document.querySelectorAll('.theme-option');

    if (currentThemeNameElement) {
        currentThemeNameElement.textContent = themeInfo[currentTheme]?.name || '清新简约';
    }

    // 更新选中状态
    themeOptions.forEach(option => {
        const theme = option.dataset.theme;
        if (theme === currentTheme) {
            option.classList.add('active');
        } else {
            option.classList.remove('active');
        }
    });
}

// 计算并绘制当前时间红线，并高亮当前课程
function updateNowLine(startTimer = false) {
    const line = document.getElementById('nowLine');
    const container = document.getElementById('scheduleContainer');
    const table = document.getElementById('scheduleTable');
    if (!line || !container || !table) return;

    // 若隐藏则不更新
    if (!nowIndicatorEnabled) return;

    const now = new Date();
    const weekday = now.getDay(); // 0=Sunday
    const hour = now.getHours();
    const minute = now.getMinutes();
    const minutesFromStart = hour * 60 + minute;

    // 根据 time_slots 定位 vertical 位置
    // time_slots: 1..13
    let topOffset = table.querySelector('thead').offsetHeight; // from top of table
    // 计算红线的 left：时间列宽度
    const timeTh = table.querySelector('thead th:first-child');
    const tableRect = table.getBoundingClientRect();
    const containerRect = container.getBoundingClientRect();
    const left = (timeTh ? timeTh.offsetWidth : 80); // fallback 80
    line.style.left = `${left}px`;
    line.style.right = `0px`;
    let matched = false;
    const firstRowHeightEl = table.querySelector(`#scheduleBody tr:nth-child(1) td`);
    const rowHeight = firstRowHeightEl ? firstRowHeightEl.offsetHeight : 60;
    const toMin = (s) => { const [h, m] = s.split(':').map(Number); return h * 60 + m; };
    const starts = []; const ends = [];
    for (let period = 1; period <= 13; period++) {
        const range = scheduleData?.time_slots?.[period];
        if (!range) continue;
        const [startStr, endStr] = range.split('-');
        starts[period] = toMin(startStr);
        ends[period] = toMin(endStr);
    }

    for (let period = 1; period <= 13; period++) {
        if (!starts[period] || !ends[period]) continue;
        if (minutesFromStart >= starts[period] && minutesFromStart <= ends[period]) {
            const ratio = (minutesFromStart - starts[period]) / (ends[period] - starts[period]);
            const y = topOffset + (period - 1 + ratio) * rowHeight;
            line.style.top = `${y}px`;
            matched = true;
            break;
        }
        // 课间落点：位于上一行底部
        if (period < 13 && minutesFromStart > ends[period] && minutesFromStart < starts[period + 1]) {
            const y = topOffset + period * rowHeight;
            line.style.top = `${y}px`;
            matched = true;
            break;
        }
    }

    if (!matched) {
        // 早于第一节或晚于最后一节
        if (minutesFromStart < starts[1]) {
            line.style.top = `${topOffset}px`;
            matched = true;
        } else if (ends[13]) {
            line.style.top = `${topOffset + 13 * rowHeight}px`;
            matched = true;
        }
    }

    if (!matched) {
        // 开启状态下但不在课时范围，隐藏可见性但保持布局
        line.style.visibility = 'hidden';
        clearCurrentCourseHighlight();
        positionTodayOverlay();
    } else {
        // 定位到当前星期列并高亮所处课程
        highlightCurrentCourse(weekday);
        line.style.visibility = 'visible';
        positionTodayOverlay();
    }

    if (startTimer && !nowLineTimer) {
        nowLineTimer = setInterval(() => updateNowLine(false), 60000);
    }
}

function clearCurrentCourseHighlight() {
    document.querySelectorAll('.course-cell.current-course').forEach(el => el.classList.remove('current-course'));
}

function highlightCurrentCourse(weekday) {
    clearCurrentCourseHighlight();
    // weekday: 0=Sun..6=Sat; our table columns 1..7 => Mon..Sun
    const colIndex = weekday === 0 ? 7 : weekday; // Sun -> 7
    const cells = document.querySelectorAll(`#scheduleBody tr`);
    const now = new Date();
    const minutesNow = now.getHours() * 60 + now.getMinutes();

    for (let period = 1; period <= cells.length; period++) {
        const range = scheduleData?.time_slots?.[period];
        if (!range) continue;
        const [startStr, endStr] = range.split('-');
        const toMin = (s) => { const [h, m] = s.split(':').map(Number); return h * 60 + m; };
        const startMin = toMin(startStr);
        const endMin = toMin(endStr);
        if (minutesNow >= startMin && minutesNow <= endMin) {
            const row = cells[period - 1];
            const tds = row.querySelectorAll('td');
            const cell = tds[colIndex]; // 0 is time column
            if (cell) {
                const courseEl = cell.querySelector('.course-cell');
                if (courseEl) courseEl.classList.add('current-course');
            }
            break;
        }
    }
}

function positionTodayOverlay() {
    const overlay = document.getElementById('todayColOverlay');
    const container = document.getElementById('scheduleContainer');
    const table = document.getElementById('scheduleTable');
    if (!overlay || overlay.style.display === 'none') return;

    const now = new Date();
    const weekday = now.getDay(); // 0..6 (Sun..Sat)
    const col = weekday === 0 ? 7 : weekday; // 1..7 (Mon..Sun)

    const timeTh = table.querySelector('thead th:first-child');
    const dayTh = table.querySelector(`thead th:nth-child(${col + 1})`);
    if (!dayTh) return;

    const left = (timeTh ? timeTh.offsetWidth : 80) + (dayTh.offsetLeft - (timeTh ? timeTh.offsetLeft + timeTh.offsetWidth : 0));
    overlay.style.left = `${left}px`;
    overlay.style.width = `${dayTh.offsetWidth}px`;
}

// 导出今日清单 CSV
function exportTodaySchedule() {
    if (!scheduleData) return;
    const now = new Date();
    const weekday = now.getDay();
    const col = weekday === 0 ? 7 : weekday; // 1..7
    const todayCourses = scheduleData.courses.filter(c => c.weekday === col);
    if (todayCourses.length === 0) {
        showSuccess('今日无课程');
        return;
    }
    let csv = '课程名称,任课教师,教室,时间段,周次,课程代码\n';
    todayCourses.forEach(c => {
        const timeRange = `${scheduleData.time_slots[c.start_period]}-${scheduleData.time_slots[c.end_period]}`;
        csv += `${c.course_name},${c.teacher},${c.location},${timeRange},${c.total_weeks},${c.course_code}\n`;
    });
    const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' });
    const link = document.createElement('a');
    link.href = URL.createObjectURL(blob);
    link.download = `今日课表_${now.toLocaleDateString()}.csv`;
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
}

// 以弹窗展示今日清单
function showTodayListModal() {
    if (!scheduleData) return;
    const now = new Date();
    const weekday = now.getDay();
    const col = weekday === 0 ? 7 : weekday;
    const todayCourses = scheduleData.courses
        .filter(c => c.weekday === col)
        .sort((a, b) => a.start_period - b.start_period);

    const body = document.getElementById('todayListBody');
    if (!body) return;
    if (todayCourses.length === 0) {
        body.innerHTML = '<div class="text-muted">今日无课程</div>';
    } else {
        const lines = todayCourses.map(c => {
            const text = (c.start_period === c.end_period)
                ? `第${c.start_period}节`
                : `${c.start_period}~${c.end_period}节`;
            return `${text}  ${c.course_name}`;
        });
        body.innerHTML = `<pre class="mb-0">${lines.join('\n')}</pre>`;
    }
    const modal = new bootstrap.Modal(document.getElementById('todayModal'));
    modal.show();
}

// 生成本周上课清单（复制到表格）
function showWeekListModal() {
    if (!scheduleData) return;
    const now = new Date();
    const weekday = now.getDay() || 7; // 周日=7
    const monday = new Date(now);
    monday.setDate(now.getDate() - weekday + 1);
    const sunday = new Date(monday);
    sunday.setDate(monday.getDate() + 6);

    const fmt = (d) => `${d.getFullYear()}年${d.getMonth()+1}月${d.getDate()}日`;
    const weekRangeText = document.getElementById('weekRangeText');
    if (weekRangeText) weekRangeText.textContent = `${fmt(monday)} - ${fmt(sunday)}`;

    const weekdayMap = {1:'一',2:'二',3:'三',4:'四',5:'五',6:'六',7:'日'};
    const getDateOfWeekday = (w) => {
        const d = new Date(monday);
        d.setDate(monday.getDate() + (w-1));
        return fmt(d);
    };

    // 准备数据用于显示和复制
    const courses = [...scheduleData.courses]
        .sort((a,b)=> (a.weekday-b.weekday) || (a.start_period-b.start_period))
        .map(c => {
            const teacher = c.teacher || (scheduleData.teacher_info?.teacher_name || '');
            const clazz = c.class_name || (scheduleData.class_info?.class_name || '');
            const name = c.course_name;
            const dateStr = getDateOfWeekday(c.weekday);
            const weekdayZh = weekdayMap[c.weekday] || '';
            const periodStr = (c.start_period === c.end_period) ? `${c.start_period}` : `${c.start_period}、${c.end_period}`;
            const place = c.location;
            const size = c.class_size || '';
            return {
                teacher: teacher,
                clazz: clazz,
                name: name,
                dateStr: dateStr,
                weekdayZh: weekdayZh,
                periodStr: periodStr,
                place: place,
                size: size
            };
        });

    // 生成Tab分隔的文本用于显示
    const lines = courses.map(c => 
        `${c.teacher}\t${c.clazz}\t${c.name}\t${c.dateStr}\t${c.weekdayZh}\t${c.periodStr}\t${c.place}\t${c.size}`
    );

    const body = document.getElementById('weekListBody');
    if (body) {
        body.textContent = lines.join('\n');
        // 存储课程数据供复制使用
        body.dataset.courses = JSON.stringify(courses);
    }
    const modal = new bootstrap.Modal(document.getElementById('weekListModal'));
    modal.show();
}

// 生成 TSV 文本（使用 \t 分列，\r\n 分行，兼容 Excel/在线表格）
function buildWeekListTSV() {
    const now = new Date();
    const weekday = now.getDay() || 7;
    const monday = new Date(now);
    monday.setDate(now.getDate() - weekday + 1);
    const fmt = (d) => `${d.getFullYear()}年${d.getMonth()+1}月${d.getDate()}日`;
    const weekdayMap = {1:'一',2:'二',3:'三',4:'四',5:'五',6:'六',7:'日'};
    const getDateOfWeekday = (w) => { const d = new Date(monday); d.setDate(monday.getDate() + (w-1)); return fmt(d); };

    const lines = [...scheduleData.courses]
        .sort((a,b)=> (a.weekday-b.weekday) || (a.start_period-b.start_period))
        .map(c => {
            const teacher = c.teacher || (scheduleData.teacher_info?.teacher_name || '');
            const clazz = c.class_name || (scheduleData.class_info?.class_name || '');
            const name = c.course_name;
            const dateStr = getDateOfWeekday(c.weekday);
            const weekdayZh = weekdayMap[c.weekday] || '';
            const periodStr = (c.start_period === c.end_period) ? `${c.start_period}` : `${c.start_period}、${c.end_period}`;
            const place = c.location;
            const size = c.class_size || '';
            return `${teacher}\t${clazz}\t${name}\t${dateStr}\t${weekdayZh}\t${periodStr}\t${place}\t${size}`;
        });
    return lines.join('\r\n');
}

// 生成 HTML 表格以提升粘贴到富文本表格时的识别率
function buildWeekListHTML(tsv) {
    const rows = tsv.split(/\r?\n/).filter(Boolean);
    const cells = rows.map(r => r.split('\t'));
    const escape = (s) => s.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
    const tr = cells.map(cols => `<tr>${cols.map(c=>`<td>${escape(c)}</td>`).join('')}</tr>`).join('');
    return `<table>${tr}</table>`;
}

async function copyWeekListToClipboard() {
    const body = document.getElementById('weekListBody');
    if (!body) return;
    
    // 获取课程数据
    let courses = [];
    try {
        courses = JSON.parse(body.dataset.courses || '[]');
    } catch (e) {
        // 如果解析失败，从文本内容重建
        const text = body.textContent;
        const lines = text.split('\n').filter(l => l.trim());
        courses = lines.map(line => {
            const parts = line.split('\t');
            return {
                teacher: parts[0] || '',
                clazz: parts[1] || '',
                name: parts[2] || '',
                dateStr: parts[3] || '',
                weekdayZh: parts[4] || '',
                periodStr: parts[5] || '',
                place: parts[6] || '',
                size: parts[7] || ''
            };
        });
    }

    // HTML转义函数
    function escapeHtml(text) {
        const div = document.createElement('div');
        div.textContent = text || '';
        return div.innerHTML;
    }

    // 确保所有课程数据完整（防止最后一列数据缺失）
    courses.forEach(c => {
        if (!c.teacher) c.teacher = '';
        if (!c.clazz) c.clazz = '';
        if (!c.name) c.name = '';
        if (!c.dateStr) c.dateStr = '';
        if (!c.weekdayZh) c.weekdayZh = '';
        if (!c.periodStr) c.periodStr = '';
        if (!c.place) c.place = '';
        if (!c.size) c.size = '';
    });

    // 生成HTML表格格式（Excel可以识别）
    // 不使用thead，只用tbody，避免表头被插入为数据行
    // 去除前后空白，避免空行
    const htmlTable = '<table border="1"><tbody>' +
        courses.map(c => 
            '<tr>' +
            '<td>' + escapeHtml(c.teacher) + '</td>' +
            '<td>' + escapeHtml(c.clazz) + '</td>' +
            '<td>' + escapeHtml(c.name) + '</td>' +
            '<td>' + escapeHtml(c.dateStr) + '</td>' +
            '<td>' + escapeHtml(c.weekdayZh) + '</td>' +
            '<td>' + escapeHtml(c.periodStr) + '</td>' +
            '<td>' + escapeHtml(c.place) + '</td>' +
            '<td>' + escapeHtml(c.size) + '</td>' +
            '</tr>'
        ).join('') +
        '</tbody></table>';

    // 生成Tab分隔的文本格式（备用，不带表头）
    const textContent = courses.map(c => 
        `${c.teacher || ''}\t${c.clazz || ''}\t${c.name || ''}\t${c.dateStr || ''}\t${c.weekdayZh || ''}\t${c.periodStr || ''}\t${c.place || ''}\t${c.size || ''}`
    ).join('\n');

    // 尝试使用Clipboard API（支持多格式）
    // 检查是否在安全上下文中且ClipboardItem可用
    if (navigator.clipboard && navigator.clipboard.write && typeof ClipboardItem !== 'undefined') {
        try {
            // 使用完整的HTML文档结构，确保Excel能正确识别
            // 注意：HTML内容不能有前后空白，否则会导致空行
            const htmlData = '<html><body>' + htmlTable + '</body></html>';
            const htmlBlob = new Blob([htmlData], { type: 'text/html' });
            const textBlob = new Blob([textContent], { type: 'text/plain' });
            
            const clipboardItem = new ClipboardItem({
                'text/html': htmlBlob,
                'text/plain': textBlob
            });

            navigator.clipboard.write([clipboardItem]).then(() => {
                showSuccess('已复制到剪贴板（Excel表格格式）');
            }).catch(err => {
                console.warn('Clipboard API写入失败，尝试备用方法:', err);
                copyUsingExecCommand(htmlTable, textContent);
            });
        } catch (err) {
            console.warn('ClipboardItem创建失败，尝试备用方法:', err);
            copyUsingExecCommand(htmlTable, textContent);
        }
    } else {
        // 使用备用方法（适用于HTTP或非安全上下文）
        copyUsingExecCommand(htmlTable, textContent);
    }
}

// 备用复制方法：使用execCommand
function copyUsingExecCommand(htmlContent, textContent) {
    // 创建一个临时的div容器用于HTML复制
    // 确保div没有任何额外的空白或样式
    const tempDiv = document.createElement('div');
    tempDiv.style.position = 'absolute';
    tempDiv.style.left = '-9999px';
    tempDiv.style.top = '0';
    tempDiv.style.width = '1px';
    tempDiv.style.height = '1px';
    tempDiv.style.overflow = 'hidden';
    tempDiv.style.padding = '0';
    tempDiv.style.margin = '0';
    tempDiv.style.border = 'none';
    // 不设置whiteSpace，让HTML表格自然渲染
    tempDiv.contentEditable = 'true';
    // 直接设置innerHTML，确保没有额外的空白
    tempDiv.innerHTML = htmlContent.trim();
    document.body.appendChild(tempDiv);

    // 选中表格内容（只选中表格本身，不包括div）
    const table = tempDiv.querySelector('table');
    if (!table) {
        // 如果没有表格，使用文本方式
        document.body.removeChild(tempDiv);
        copyTextFallback(textContent);
        return;
    }

    const range = document.createRange();
    range.selectNodeContents(table);
    const selection = window.getSelection();
    selection.removeAllRanges();
    selection.addRange(range);

    try {
        // 尝试复制HTML格式（execCommand会保留HTML格式）
        const success = document.execCommand('copy');
        if (success) {
            showSuccess('已复制到剪贴板（Excel表格格式）');
            // 清理
            selection.removeAllRanges();
            document.body.removeChild(tempDiv);
            return;
        } else {
            throw new Error('execCommand复制失败');
        }
    } catch (err) {
        console.warn('execCommand HTML复制失败，尝试文本格式:', err);
        // 清理HTML元素
        selection.removeAllRanges();
        document.body.removeChild(tempDiv);
        
        // 使用文本方式复制
        copyTextFallback(textContent);
    }
}

// 文本复制备用方法
function copyTextFallback(textContent) {
    const textarea = document.createElement('textarea');
    textarea.value = textContent;
    textarea.style.position = 'fixed';
    textarea.style.left = '-9999px';
    textarea.style.top = '0';
    textarea.style.opacity = '0';
    document.body.appendChild(textarea);
    textarea.focus();
    textarea.select();
    try {
        const textSuccess = document.execCommand('copy');
        if (textSuccess) {
            showSuccess('已复制到剪贴板（文本格式，粘贴到Excel时会自动分列）');
        } else {
            throw new Error('文本复制失败');
        }
    } catch (e) {
        console.error('文本复制也失败:', e);
        showError('复制失败，请手动选择复制');
    } finally {
        document.body.removeChild(textarea);
    }
}

// 绑定事件
function bindEvents() {
    // 课程单元格点击事件
    document.addEventListener('click', function(e) {
        if (e.target.closest('.course-cell')) {
            const courseData = JSON.parse(e.target.closest('.course-cell').dataset.course);
            showCourseDetail(courseData.course_name);
        }
    });

    // 主题选择事件
    document.addEventListener('click', function(e) {
        if (e.target.closest('.theme-option')) {
            e.preventDefault();
            const theme = e.target.closest('.theme-option').dataset.theme;
            switchTheme(theme);
        }
    });

    // 导出课表为图片
    const exportImageBtn = document.getElementById('exportImageBtn');
    if (exportImageBtn) {
        exportImageBtn.addEventListener('click', exportScheduleImage);
    }

    // 打印功能
    document.getElementById('printBtn').addEventListener('click', function() {
        window.print();
    });

    // 当前时间红线开关
    const toggleBtn = document.getElementById('toggleNowLineBtn');
    if (toggleBtn) {
        toggleBtn.addEventListener('click', function() {
            const line = document.getElementById('nowLine');
            const overlay = document.getElementById('todayColOverlay');
            if (!line) return;
            nowIndicatorEnabled = !nowIndicatorEnabled;
            if (nowIndicatorEnabled) {
                line.style.display = 'block';
                line.style.visibility = 'hidden';
                if (overlay) overlay.style.display = 'block';
                updateNowLine(true);
            } else {
                line.style.display = 'none';
                if (overlay) overlay.style.display = 'none';
                clearCurrentCourseHighlight();
                if (nowLineTimer) {
                    clearInterval(nowLineTimer);
                    nowLineTimer = null;
                }
            }
        });
    }

    // 导出今日清单
    const exportTodayBtn = document.getElementById('exportTodayBtn');
    if (exportTodayBtn) {
        exportTodayBtn.addEventListener('click', showTodayListModal);
    }

    // 周清单导出/复制
    const exportWeekListBtn = document.getElementById('exportWeekListBtn');
    if (exportWeekListBtn) {
        exportWeekListBtn.addEventListener('click', showWeekListModal);
    }
    const copyWeekListBtn = document.getElementById('copyWeekListBtn');
    if (copyWeekListBtn) {
        copyWeekListBtn.addEventListener('click', copyWeekListToClipboard);
    }
}

// 导出课程表
function exportSchedule() {
    // 已废弃 CSV 导出
}

// 工具函数
function showLoading() {
    const overlay = document.getElementById('loadingOverlay');
    if (overlay) {
        overlay.style.display = 'flex';
    }
}

function hideLoading() {
    const overlay = document.getElementById('loadingOverlay');
    if (overlay) {
        overlay.style.display = 'none';
    }
}

function showError(message) {
    const alertDiv = document.createElement('div');
    alertDiv.className = 'alert alert-danger alert-dismissible fade show position-fixed';
    alertDiv.style.top = '20px';
    alertDiv.style.right = '20px';
    alertDiv.style.zIndex = '9999';
    alertDiv.innerHTML = `
        ${message}
        <button type="button" class="btn-close" data-bs-dismiss="alert"></button>
    `;
    
    document.body.appendChild(alertDiv);
    
    setTimeout(() => {
        if (alertDiv.parentNode) {
            alertDiv.parentNode.removeChild(alertDiv);
        }
    }, 5000);
}

function showSuccess(message) {
    const alertDiv = document.createElement('div');
    alertDiv.className = 'alert alert-success alert-dismissible fade show position-fixed';
    alertDiv.style.top = '20px';
    alertDiv.style.right = '20px';
    alertDiv.style.zIndex = '9999';
    alertDiv.innerHTML = `
        ${message}
        <button type="button" class="btn-close" data-bs-dismiss="alert"></button>
    `;
    
    document.body.appendChild(alertDiv);
    
    setTimeout(() => {
        if (alertDiv.parentNode) {
            alertDiv.parentNode.removeChild(alertDiv);
        }
    }, 3000);
}
